// Copyright (c) Appeon. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

namespace SnapObjects.Data
{
    /// <summary>
    ///     Represents an object, that uses AND or OR logical operator and adds a search condition in the HAVING clause of a SQL statement. 
    ///     The return values of all methods are always the current ISqlHavingAndOr object.
    /// </summary>
    public interface ISqlHavingAndOr : ISqlHavingAndOr<ISqlHavingAndOr>, ISqlOrderBuilder
    {

    }

    /// <summary>
    ///     Represents an object, that uses AND or OR logical operator and adds a search condition in the HAVING clause of a SQL statement. 
    ///     The return values of all methods are always the current TBuilder object.
    /// </summary>
    /// <typeparam name="TBuilder"></typeparam>
    public interface ISqlHavingAndOr<TBuilder>
    {
        /// <summary>
        ///     Adds the AND logical operator and a search condition to the HAVING clause. Specifies a SQL expression on the left the 
        ///     operator and a specific value on the right of the operator. The operator is '='.
        /// </summary>
        /// <param name="left">An expression on the left of the operator.</param>
        /// <param name="value">The specific value on the right of the operator.</param>
        /// <returns>
        ///     Returns the TBuilder object which can be used to add more search conditions to the current HAVING clause.
        /// </returns>
        TBuilder AndHavingValue(string left, object value);

        /// <summary>
        ///     Adds the AND logical operator and a search condition to the HAVING clause. Specifies a SQL expression on the left the 
        ///     operator and a specific value on the right of the operator.
        /// </summary>
        /// <param name="left">An expression on the left of the operator.</param>
        /// <param name="sqlOperator">
        ///     An enumeration value of SqlBinaryOperator, which is the operator to test the expression on the left and the value on the right.
        /// </param>
        /// <param name="value">The specific value on the right of the operator.</param>
        /// <returns>
        ///     Returns the TBuilder object which can be used to add more search conditions to the current HAVING clause.
        /// </returns>
        TBuilder AndHavingValue(string left, SqlBinaryOperator sqlOperator, object value);

        /// <summary>
        ///     Adds the AND logical operator and a search condition to the HAVING clause. Specifies a SQL expression to the left of the 
        ///     operator and a SQL parameter to the right of the operator. The operator is '='.
        /// </summary>
        /// <param name="left">A SQL expression on the left of the operator.</param>
        /// <param name="parameter">
        ///     An ISqlParameter object which represents a SQL parameter on the right of the operator. 
        ///     It can be created by calling the SqlBuilder.Parameter method.
        /// </param>
        /// <returns>
        ///     Returns the TBuilder object which can be used to add more search conditions to the current HAVING clause.
        /// </returns>
        TBuilder AndHaving(string left, ISqlParameter parameter);

        /// <summary>
        ///     Adds the AND logical operator and a search condition to the HAVING clause. Specifies a SQL expression to the left of the
        ///     operator and a SQL parameter to the right of the operator.
        /// </summary>
        /// <param name="left">A SQL expression to the left of the operator.</param>
        /// <param name="sqlOperator">
        ///     An enumeration value of SqlBinaryOperator, which is the operator to test the two expressions on the left and right.
        /// </param>
        /// <param name="parameter">
        ///     An ISqlParameter object which represents a SQL parameter to the right of the operator. 
        ///     It can be created by calling the SqlBuilder.Parameter method.
        /// </param>
        /// <returns>
        ///     Returns the TBuilder object which can be used to add more search conditions to the current HAVING clause.
        /// </returns>
        TBuilder AndHaving(string left, SqlBinaryOperator sqlOperator, ISqlParameter parameter);

        /// <summary>
        ///     Adds the AND logical operator and a search condition to the HAVING clause. Specifies SQL expressions on both the left
        ///     and right of the operator. The operator is '='.
        /// </summary>
        /// <param name="left">A SQL expression to the left of the operator.</param>
        /// <param name="right">A SQL expression to the right of the operator.</param>
        /// <returns>
        ///     Returns the TBuilder object which can be used to add more search conditions to the current HAVING clause.
        /// </returns>
        TBuilder AndHaving(string left, string right);

        /// <summary>
        ///     Adds the AND logical operator and a search condition to the HAVING clause. Specifies SQL expressions on both the left 
        ///     and right of the operator.
        /// </summary>
        /// <param name="left">A SQL expression on the left of the operator.</param>
        /// <param name="sqlOperator">
        ///     An enumeration value of SqlBinaryOperator, which is the operator to test the two expressions on the left and right.
        /// </param>
        /// <param name="right">A SQL expression to the right of the operator.</param>
        /// <returns>
        ///      Returns the TBuilder object which can be used to add more search conditions to the current HAVING clause.
        /// </returns>
        TBuilder AndHaving(string left, SqlBinaryOperator sqlOperator, string right);

        /// <summary>
        ///     Adds the AND logical operator and a search condition to the HAVING clause. Specifies a SQL expression on the left of 
        ///     the operator and a SQL subquery on the right of the operator. The operator is '='.
        /// </summary>
        /// <param name="left">A SQL expression on the left of the operator.</param>
        /// <param name="sqlBuilder">
        ///     An ISqlBuilder object which represents a SQL subquery on the right of the operator.
        /// </param>
        /// <returns>
        ///     Returns the TBuilder object which can be used to add more search conditions to the current HAVING clause.
        /// </returns>
        TBuilder AndHaving(string left, ISqlBuilder sqlBuilder);

        /// <summary>
        ///     Adds the AND logical operator and a search condition to the HAVING clause. Specifies a SQL expression on the left of 
        ///     the operator and a SQL subquery on the right of the operator.
        /// </summary>
        /// <param name="left">A SQL expression on the left of the operator.</param>
        /// <param name="sqlOperator">
        ///     An enumeration value of SqlBinaryOperator, which is the operator to test the two expressions on the left and right.
        /// </param>
        /// <param name="sqlBuilder">
        ///     An ISqlBuilder object which represents a SQL subquery on the right of the operator.
        /// </param>
        /// <returns>
        ///     Returns the TBuilder object which can be used to add more search conditions to the current HAVING clause.
        /// </returns>
        TBuilder AndHaving(string left, SqlBinaryOperator sqlOperator, ISqlBuilder sqlBuilder);

        /// <summary>
        ///     Adds the AND logical operator and a search condition (specified by an ISqlHavingCondition object) to the HAVING clause.
        /// </summary>
        /// <param name="condition">
        ///     An ISqlHavingCondition object which represents a search condition in the HAVING clause. 
        ///     This object can be created by using the SqlBuilder.Having method and so on.
        /// </param>
        /// <returns>
        ///     Returns the TBuilder object which can be used to add more search conditions to the current HAVING clause.
        /// </returns>
        TBuilder AndHaving(ISqlHavingCondition condition);

        /// <summary>
        ///     Adds the AND logical operator and a search condition (specified by an ISqlHavingCondition object) to the HAVING clause. 
        ///     You can specify an alias for the search condition.
        /// </summary>
        /// <param name="condition">
        ///     An ISqlHavingCondition object which represents a search condition in the HAVING clause. 
        ///     This object can be created by using the SqlBuilder.Having method and so on.
        /// </param>
        /// <param name="alias">An alias for the search condition.</param>
        /// <returns>
        ///     Returns the TBuilder object which can be used to add more search conditions to the current HAVING clause.
        /// </returns>
        TBuilder AndHaving(ISqlHavingCondition condition, string alias);

        /// <summary>
        ///     Adds the AND logical operator and a raw SQL to the HAVING clause.
        /// </summary>
        /// <param name="clause">A string of raw SQL to be added to the HAVING clause.</param>
        /// <param name="parameters">
        ///     (Optional) An array of ISqlParameter objects which define the SQL parameters used in the raw SQL.
        /// </param>
        /// <returns>
        ///     Returns the TBuilder object which can be used to add more search conditions to the current HAVING clause.
        /// </returns>
        TBuilder AndHavingRaw(string clause, params ISqlParameter[] parameters);

        /// <summary>
        ///     Adds the AND logical operator and a raw SQL string to the HAVING clause. You need to specify an alias for the raw SQL.
        /// </summary>
        /// <param name="clause">A string of raw SQL to be added to the HAVING clause.</param>
        /// <param name="alias">The alias specified for the raw SQL.</param>
        /// <param name="parameters">
        ///     (Optional) An array of ISqlParameter objects which define the SQL parameters used in the raw SQL.
        /// </param>
        /// <returns>
        ///     Returns the TBuilder object which can be used to add more search conditions to the current HAVING clause.
        /// </returns>
        TBuilder AndHavingRaw(string clause, string alias, params ISqlParameter[] parameters);

        /// <summary>
        ///     Adds the OR logical operator and a search condition to the HAVING clause. Specifies the SQL expression on the left 
        ///     the operator and a specific value on the right of the operator. The operator is '='.
        /// </summary>
        /// <param name="left">An expression on the left of the operator.</param>
        /// <param name="value">The specific value on the right of the operator.</param>
        /// <returns>
        ///     Returns the TBuilder object which can be used to add more search conditions to the current HAVING clause.
        /// </returns>
        TBuilder OrHavingValue(string left, object value);

        /// <summary>
        ///     Adds the OR logical operator and a search condition to the HAVING clause. Specifies a SQL expression on the left 
        ///     the operator and a specific value on the right of the operator.
        /// </summary>
        /// <param name="left">An expression on the left of the operator.</param>
        /// <param name="sqlOperator">
        ///     An enumeration value of SqlBinaryOperator, which is the operator to test the expression on the left and the value on the right.
        /// </param>
        /// <param name="value">
        ///     The specific value on the right of the operator.
        /// </param>
        /// <returns>
        ///     Returns the TBuilder object which can be used to add more search conditions to the current HAVING clause.
        /// </returns>
        TBuilder OrHavingValue(string left, SqlBinaryOperator sqlOperator, object value);

        /// <summary>
        ///     Adds the OR logical operator and a search condition to the HAVING clause. Specifies a SQL expression on the 
        ///     left of the operator and a SQL parameter on the right of the operator. The operator is '='.
        /// </summary>
        /// <param name="left">A SQL expression on the left of the operator.</param>
        /// <param name="parameter">
        ///     An ISqlParameter object which represents a SQL parameter on the right of the operator.
        ///     It can be created by calling the SqlBuilder.Parameter method.
        /// </param>
        /// <returns>
        ///     Returns the TBuilder object which can be used to add more search conditions to the current HAVING clause.
        /// </returns>
        TBuilder OrHaving(string left, ISqlParameter parameter);

        /// <summary>
        ///     Adds the OR logical operator and a search condition to the HAVING clause. Specifies a SQL expression to the
        ///     left of the operator and a SQL parameter to the right of the operator.
        /// </summary>
        /// <param name="left">A SQL expression on the left of the operator.</param>
        /// <param name="sqlOperator">
        ///     An enumeration value of SqlBinaryOperator, which is the operator to test the two expressions on the left and right.
        /// </param>
        /// <param name="parameter">
        ///     An ISqlParameter object which represents a SQL parameter on the right of the operator.
        ///     It can be created by calling the SqlBuilder.Parameter method.
        /// </param>
        /// <returns>
        ///     Returns the TBuilder object which can be used to add more search conditions to the current HAVING clause.
        /// </returns>
        TBuilder OrHaving(string left, SqlBinaryOperator sqlOperator, ISqlParameter parameter);

        /// <summary>
        ///     Adds the OR logical operator and a search condition to the HAVING clause. Specifies SQL expressions on both the 
        ///     left and right of the operator. The operator is '='.
        /// </summary>
        /// <param name="left">A SQL expression on the left of the operator.</param>
        /// <param name="right">A SQL expression on the right of the operator.</param>
        /// <returns>
        ///     Returns the TBuilder object which can be used to add more search conditions to the current HAVING clause.
        /// </returns>
        TBuilder OrHaving(string left, string right);

        /// <summary>
        ///     Adds the OR logical operator and a search condition to the HAVING clause. Specifies SQL expressions 
        ///     on both the left and right of the operator.
        /// </summary>
        /// <param name="left">A SQL expression on the left of the operator.</param>
        /// <param name="sqlOperator">
        ///     An enumeration value of SqlBinaryOperator, which is the operator to test the two expressions on the left and right.
        /// </param>
        /// <param name="right">A SQL expression on the right of the operator.</param>
        /// <returns>
        ///     Returns the TBuilder object which can be used to add more search conditions to the current HAVING clause.
        /// </returns>
        TBuilder OrHaving(string left, SqlBinaryOperator sqlOperator, string right);

        /// <summary>
        ///     Adds the OR logical operator and a search condition to the HAVING clause. Specifies a SQL expression on the left of
        ///     the operator and a SQL subquery on the right of the operator. The operator is '='.
        /// </summary>
        /// <param name="left">A SQL expression on the left of the operator.</param>
        /// <param name="sqlBuilder">
        ///     An ISqlBuilder object which represents a SQL subquery on the right of the operator.
        /// </param>
        /// <returns>
        ///     Returns the TBuilder object which can be used to add more search conditions to the current HAVING clause.
        /// </returns>
        TBuilder OrHaving(string left, ISqlBuilder sqlBuilder);

        /// <summary>
        ///     Adds the OR logical operator and a search condition to the HAVING clause. Specifies a SQL expression on the left of
        ///     the operator and a SQL subquery on the right of the operator.
        /// </summary>
        /// <param name="left">A SQL expression on the left of the operator.</param>
        /// <param name="sqlOperator">
        ///     An enumeration value of SqlBinaryOperator, which is the operator to test the two expressions on the left and right.
        /// </param>
        /// <param name="sqlBuilder">
        ///     An ISqlBuilder object which represents a SQL subquery on the right of the operator.
        /// </param>
        /// <returns>
        ///     Returns the TBuilder object which can be used to add more search conditions to the current HAVING clause.
        /// </returns>
        TBuilder OrHaving(string left, SqlBinaryOperator sqlOperator, ISqlBuilder sqlBuilder);

        /// <summary>
        ///     Adds the OR logical operator and a search condition (specified by an ISqlHavingCondition object) to the HAVING clause.
        /// </summary>
        /// <param name="condition">
        ///     An ISqlHavingCondition object which represents a search condition of the HAVING clause.
        ///     This object can be created by using the SqlBuilder.Having method and so on.
        /// </param>
        /// <returns>
        ///     Returns the TBuilder object which can be used to add more search conditions to the current HAVING clause.
        /// </returns>
        TBuilder OrHaving(ISqlHavingCondition condition);

        /// <summary>
        ///     Adds the OR logical operator and a search condition (specified by an ISqlHavingCondition object) to the HAVING clause. 
        ///     You can specify an alias for the search condition.
        /// </summary>
        /// <param name="condition">
        ///     An ISqlHavingCondition object which represents a search condition of the HAVING clause.
        ///     This object can be created by using the SqlBuilder.Having method and so on.
        /// </param>
        /// <param name="alias">An alias for the search condition.</param>
        /// <returns>
        ///     Returns the TBuilder object which can be used to add more search conditions to the current HAVING clause.
        /// </returns>
        TBuilder OrHaving(ISqlHavingCondition condition, string alias);

        /// <summary>
        ///     Adds the OR logical operator and a raw SQL to the HAVING clause.
        /// </summary>
        /// <param name="clause">A string of raw SQL to be added to the HAVING clause.</param>
        /// <param name="parameters">
        ///     (Optional) An array of ISqlParameter objects which define the SQL parameters used in the raw SQL.
        /// </param>
        /// <returns>
        ///     Returns the TBuilder object which can be used to add more search conditions to the current HAVING clause.
        /// </returns>
        TBuilder OrHavingRaw(string clause, params ISqlParameter[] parameters);

        /// <summary>
        ///     Adds the OR logical operator and a raw SQL to the HAVING clause. You need to specify an alias for the raw SQL.
        /// </summary>
        /// <param name="clause">A string of raw SQL to be added to the HAVING clause.</param>
        /// <param name="alias">The alias specified for the raw SQL.</param>
        /// <param name="parameters">
        ///     (Optional) An array of ISqlParameter objects which define the SQL parameters used in the raw SQL.
        /// </param>
        /// <returns>
        ///     Returns the TBuilder object which can be used to add more search conditions to the current HAVING clause.
        /// </returns>
        TBuilder OrHavingRaw(string clause, string alias, params ISqlParameter[] parameters);
    }
}
